// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.designer.ui.login;

import java.lang.reflect.InvocationTargetException;

import org.dengues.core.DenguesCorePlugin;
import org.dengues.core.resource.DenguesProject;
import org.dengues.core.resource.DenguesProjectFactory;
import org.dengues.designer.ui.i18n.Messages;
import org.dengues.designer.ui.wizards.NewProjectWizard;
import org.dengues.model.project.UserType;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf 1 2006-09-29 17:06:40Z qiang.zhang $
 * 
 */
public class LoginDenguesDialog extends TitleAreaDialog {

    private static final int DEFALUT_LENGTH = 100;

    private static int horizontalMerge = 85;

    private static final int VERTICAL_SPACE = 5;

    private static final int HORIZONTAL_SPACE = 5;

    private FormToolkit toolkit;

    private Button fillProjectsBtn;

    private ComboViewer projectViewer;

    private Button newProjectButton;

    private DenguesProject[] readProjects;

    private Button removePrjButton;

    private Button importDemosButton;

    /**
     * Qiang.Zhang.Adolf@gmail.com LoginDenguesDialog constructor comment.
     * 
     * @param parentShell
     */
    public LoginDenguesDialog(Shell parentShell) {
        super(parentShell);
        setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | getDefaultOrientation() | SWT.RESIZE);
        RGB rgb = new RGB(255, 255, 255);
        setTitleAreaColor(rgb);
        readProjects = DenguesProjectFactory.readProjects();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
     */
    @Override
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        newShell.setSize(400, 320);
        newShell.setText(Messages.getString("LoginDialog.Title")); //$NON-NLS-1$
        Rectangle screen = Display.getDefault().getBounds();
        newShell.setLocation(screen.width / 2 - 200, screen.height / 2 - 160);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
     */
    @Override
    protected Control createDialogArea(Composite parent) {
        final Composite control = (Composite) super.createDialogArea(parent);

        toolkit = new FormToolkit(control.getDisplay());
        Form form = toolkit.createForm(control);
        Composite formBody = form.getBody();

        formBody.setBackgroundMode(SWT.INHERIT_DEFAULT);

        GridLayout layout = new GridLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        control.setLayout(layout);
        form.setLayoutData(new GridData(GridData.FILL_BOTH));

        layout = new GridLayout(3, false);
        formBody.setLayout(layout);

        // Project
        Group group = new Group(formBody, SWT.NONE);
        group.setText(Messages.getString("LoginDialog.project")); //$NON-NLS-1$
        GridData projectGroupData = new GridData(GridData.FILL_HORIZONTAL);
        projectGroupData.horizontalSpan = 3;
        group.setLayoutData(projectGroupData);

        FormData data;

        FormLayout groupLayout = new FormLayout();
        group.setLayout(groupLayout);

        // Fill projects
        fillProjectsBtn = toolkit.createButton(group, null, SWT.PUSH);
        fillProjectsBtn.setText(Messages.getString("LoginDialog.refresh")); //$NON-NLS-1$
        data = new FormData();
        data.right = new FormAttachment(DEFALUT_LENGTH, -HORIZONTAL_SPACE);
        fillProjectsBtn.setLayoutData(data);

        projectViewer = new ComboViewer(group, SWT.BORDER | SWT.READ_ONLY);
        data = new FormData();
        data.left = new FormAttachment(0, horizontalMerge + 2);
        data.right = new FormAttachment(fillProjectsBtn, -HORIZONTAL_SPACE);
        data.bottom = new FormAttachment(fillProjectsBtn, 0, SWT.CENTER);
        projectViewer.getControl().setLayoutData(data);
        projectViewer.setContentProvider(new ArrayContentProvider());
        projectViewer.setLabelProvider(new ProjectLabelProvider());
        projectViewer.getControl().setEnabled(false);

        Label existingLabel = toolkit.createLabel(group, Messages.getString("LoginDialog.exist")); //$NON-NLS-1$
        data = new FormData();
        data.left = new FormAttachment(0, HORIZONTAL_SPACE);
        data.bottom = new FormAttachment(projectViewer.getControl(), 0, SWT.CENTER);
        existingLabel.setLayoutData(data);

        // Bottom buttons:
        Composite bottomButtons = toolkit.createComposite(group);
        data = new FormData();
        data.top = new FormAttachment(projectViewer.getControl(), VERTICAL_SPACE, SWT.BOTTOM);
        data.left = new FormAttachment(projectViewer.getControl(), 0, SWT.LEFT);
        bottomButtons.setLayoutData(data);
        bottomButtons.setLayout(new FormLayout());

        Label newProjectLabel = toolkit.createLabel(group, Messages.getString("LoginDialog.new")); //$NON-NLS-1$
        data = new FormData();
        data.left = new FormAttachment(0, HORIZONTAL_SPACE);
        data.bottom = new FormAttachment(bottomButtons, 0, SWT.CENTER);
        newProjectLabel.setLayoutData(data);

        newProjectButton = toolkit.createButton(bottomButtons, null, SWT.PUSH);
        newProjectButton.setText(Messages.getString("LoginDialog.newProject")); //$NON-NLS-1$
        FormData formData = new FormData();
        formData.left = new FormAttachment(0);
        newProjectButton.setLayoutData(formData);

        removePrjButton = toolkit.createButton(bottomButtons, null, SWT.PUSH);
        removePrjButton.setText(Messages.getString("LoginDenguesDialog.delete.project")); //$NON-NLS-1$
        formData = new FormData();
        formData.left = new FormAttachment(newProjectButton, 0);
        removePrjButton.setLayoutData(formData);

        importDemosButton = toolkit.createButton(bottomButtons, null, SWT.PUSH);
        importDemosButton.setText(Messages.getString("LoginDenguesDialog.ImportDemos")); //$NON-NLS-1$
        formData = new FormData();
        formData.left = new FormAttachment(removePrjButton, 0);
        importDemosButton.setLayoutData(formData);

        addListeners();
        addProjectInfoComposite(formBody);
        populateProjectList();
        Label titleBarSeparator = new Label(control, SWT.HORIZONTAL | SWT.SEPARATOR);
        titleBarSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        return control;
    }

    private Text timetext;

    private Text versiontext;

    private Text nametext;

    private Group infogroup;

    private Text userEmailtext;

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "addProjectInfoComposite".
     * 
     * @param formBody
     */
    private void addProjectInfoComposite(Composite formBody) {
        infogroup = new Group(formBody, SWT.NONE);
        infogroup.setText(Messages.getString("LoginDialog.info")); //$NON-NLS-1$
        infogroup.setEnabled(false);

        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        gridData.horizontalSpan = 3;
        infogroup.setLayoutData(gridData);

        FormLayout groupLayout = new FormLayout();
        infogroup.setLayout(groupLayout);

        Label namelabel = new Label(infogroup, SWT.NONE);

        namelabel.setText(Messages.getString("LoginDialog.name")); //$NON-NLS-1$
        nametext = new Text(infogroup, SWT.NONE);
        if (project != null) {
            nametext.setText(project.getName());
        }

        FormData data;
        data = new FormData();
        data.left = new FormAttachment(0, HORIZONTAL_SPACE);
        data.bottom = new FormAttachment(nametext, 0, SWT.CENTER);
        namelabel.setLayoutData(data);

        data = new FormData();
        data.left = new FormAttachment(namelabel, 30);
        nametext.setLayoutData(data);

        Label versionlabel = new Label(infogroup, SWT.NONE);
        versiontext = new Text(infogroup, SWT.NONE);
        if (project != null) {
            versiontext.setText(project.getProjectType().getVersion());
        }
        data = new FormData();
        data.top = new FormAttachment(namelabel, VERTICAL_SPACE, SWT.BOTTOM);
        data.left = new FormAttachment(namelabel, 0, SWT.LEFT);
        // data.bottom = new FormAttachment(versiontext, 0, SWT.CENTER);
        versionlabel.setLayoutData(data);

        data = new FormData();
        data.top = new FormAttachment(nametext, VERTICAL_SPACE, SWT.BOTTOM);
        data.left = new FormAttachment(nametext, 0, SWT.LEFT);
        versiontext.setLayoutData(data);

        versionlabel.setText(Messages.getString("LoginDialog.version")); //$NON-NLS-1$
        Label timelabel = new Label(infogroup, SWT.NONE);
        timelabel.setText(Messages.getString("LoginDialog.time")); //$NON-NLS-1$
        timetext = new Text(infogroup, SWT.NONE);
        if (project != null) {
            timetext.setText(project.getProjectType().getCreateTime().toString());
        }

        data = new FormData();
        data.top = new FormAttachment(versionlabel, VERTICAL_SPACE, SWT.BOTTOM);
        data.left = new FormAttachment(versionlabel, 0, SWT.LEFT);
        timelabel.setLayoutData(data);

        data = new FormData();
        data.top = new FormAttachment(versiontext, VERTICAL_SPACE, SWT.BOTTOM);
        data.left = new FormAttachment(versiontext, 0, SWT.LEFT);
        timetext.setLayoutData(data);

        Label userEmaillabel = new Label(infogroup, SWT.NONE);
        userEmaillabel.setText(Messages.getString("NewProjectWizardPage.userEmail")); //$NON-NLS-1$
        userEmailtext = new Text(infogroup, SWT.NONE);
        if (project != null) {
            userEmailtext.setText(project.getProjectType().getUser().get(0).getEMail());
        }

        data = new FormData();
        data.top = new FormAttachment(timelabel, VERTICAL_SPACE, SWT.BOTTOM);
        data.left = new FormAttachment(timelabel, 0, SWT.LEFT);
        userEmaillabel.setLayoutData(data);

        data = new FormData();
        data.top = new FormAttachment(timetext, VERTICAL_SPACE, SWT.BOTTOM);
        data.left = new FormAttachment(timetext, 0, SWT.LEFT);
        userEmailtext.setLayoutData(data);

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
     */
    @Override
    protected void createButtonsForButtonBar(Composite parent) {
        createButton(parent, IDialogConstants.OK_ID, Messages.getString("LoginDenguesDialog.ok"), true); //$NON-NLS-1$
        createButton(parent, IDialogConstants.CANCEL_ID, Messages.getString("LoginDenguesDialog.cancel"), false); //$NON-NLS-1$
        updateButtons();
    }

    private void updateButtons() {
        getButton(IDialogConstants.OK_ID).setEnabled(canFinish());
        if (projectViewer.getCombo().getItemCount() > 0) {
            removePrjButton.setEnabled(true);
        } else {
            removePrjButton.setEnabled(false);
        }
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "canFinish".
     * 
     * @return
     */
    private boolean canFinish() {
        return validateProject();
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "validateProject".
     * 
     * @return
     */
    private boolean validateProject() {
        String errorMsg = null;
        boolean valid = true;
        if (getProjectName().length() == 0) {
            valid = false;
            errorMsg = Messages.getString("LoginDialog.errorMsg"); //$NON-NLS-1$
        }
        if (!valid) {
            setErrorMessage(errorMsg);
        } else {
            setErrorMessage(null);
        }
        return valid;
    }

    private DenguesProject project;

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "addListeners".
     */
    private void addListeners() {
        projectViewer.addSelectionChangedListener(new ISelectionChangedListener() {

            public void selectionChanged(SelectionChangedEvent event) {
                project = (DenguesProject) ((StructuredSelection) projectViewer.getSelection()).getFirstElement();
                updateProjectInfo();
            }

        });
        newProjectButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                NewProjectWizard newPrjWiz = new NewProjectWizard();
                WizardDialog newProjectDialog = new WizardDialog(getShell(), newPrjWiz);
                newProjectDialog.setTitle(Messages.getString("LoginDialog.newproj")); //$NON-NLS-1$
                newProjectDialog.setPageSize(200, 200);
                if (newProjectDialog.open() == WizardDialog.OK) {
                    project = newPrjWiz.getProject();
                    readProjects = DenguesProjectFactory.readProjects();
                    populateProjectList();
                    selectProject(project);
                    updateButtons();

                }
            }

        });
        removePrjButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                try {
                    String[] strings = new String[] { Messages.getString("LoginDenguesDialog.ok"), //$NON-NLS-1$
                            Messages.getString("LoginDenguesDialog.cancel") }; //$NON-NLS-1$
                    MessageDialog dialog = new MessageDialog(getParentShell(), Messages
                            .getString("LoginDenguesDialog.Delete.Project.title"), null, //$NON-NLS-1$
                            Messages.getString("LoginDenguesDialog.Delete.Project.message"), MessageDialog.QUESTION, strings, 0); //$NON-NLS-1$
                    if (dialog.open() == MessageDialog.OK) {
                        project.getProject().delete(true, null);
                        readProjects = DenguesProjectFactory.readProjects();
                        populateProjectList();
                        updateButtons();
                    }
                } catch (CoreException ex) {
                    ex.printStackTrace();
                }
            }

        });

        importDemosButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                try {
                    try {
                        IRunnableWithProgress op = new IRunnableWithProgress() {

                            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                                DenguesCorePlugin.getDefault().getDesignerCoreService().importDemoProject(getShell(), monitor);
                                Display.getDefault().asyncExec(new Runnable() {

                                    /*
                                     * (non-Javadoc)
                                     * 
                                     * @see java.lang.Runnable#run()
                                     */
                                    public void run() {
                                        readProjects = DenguesProjectFactory.readProjects();
                                        populateProjectList();
                                        updateButtons();
                                    }
                                });
                            }
                        };
                        new ProgressMonitorDialog(Display.getCurrent().getActiveShell()).run(true, false, op);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                } catch (Exception exception) {
                    exception.printStackTrace();
                }

            }

        });
        fillProjectsBtn.addSelectionListener(new SelectionAdapter() {

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
             */
            @Override
            public void widgetSelected(SelectionEvent e) {
                readProjects = DenguesProjectFactory.readProjects();
                populateProjectList();
                updateButtons();
            }

        });
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "selectProject".
     * 
     * @param project
     */
    private void selectProject(DenguesProject project) {
        projectViewer.setSelection(new StructuredSelection(new Object[] { project }));
    }

    private void populateProjectList() {
        projectViewer.setInput(readProjects);
        if (readProjects.length > 0) {
            projectViewer.getCombo().select(0);
            projectViewer.getControl().setEnabled(true);
            project = readProjects[0];
            updateProjectInfo();
        } else {
            projectViewer.getControl().setEnabled(false);
        }
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "updateProjectInfo".
     */
    private void updateProjectInfo() {
        if (project != null && infogroup != null && !infogroup.isDisposed()) {
            nametext.setText(project.getProjectType().getName());
            versiontext.setText(project.getProjectType().getVersion());
            timetext.setText(project.getProjectType().getCreateTime());
            UserType user = project.getProjectType().getUser().get(0);
            if (user != null) {
                userEmailtext.setText(user.getEMail() == null ? "" : user.getEMail()); //$NON-NLS-1$
            } else {
                userEmailtext.setText(""); //$NON-NLS-1$
            }
            infogroup.layout();
        }
    }

    private class ProjectLabelProvider extends LabelProvider {

        /**
         * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
         */
        @Override
        public String getText(Object element) {
            DenguesProject prj = (DenguesProject) element;
            String toReturn = prj.getName() + "(" + prj.getProjectType().getVersion() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
            return toReturn;
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.Dialog#okPressed()
     */
    @Override
    protected void okPressed() {
        DenguesProjectFactory.getDenguesProject(getProjectName());
        super.okPressed();
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getProjectName".
     * 
     * @return
     */
    private String getProjectName() {
        String text = projectViewer.getCombo().getText();
        if (text.contains("(") && text.contains(")")) { //$NON-NLS-1$ //$NON-NLS-2$
            text = text.substring(0, text.indexOf("(")); //$NON-NLS-1$
        }
        return text;
    }
}
